package pl.th.permission.plugin.node.annotation;

import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AnnotationNode;

import java.util.Objects;

import pl.th.permission.plugin.Utils;

public class CallbackAnnotation extends AnnotationNode {

    protected final AnnType mAnnType;

    public CallbackAnnotation(AnnType type) {
        super(Opcodes.ASM7, Utils.getAnnDesByType(type));
        if (!checkAnnotationType(type)) {
            throw new RuntimeException(this.getClass().getSimpleName() + ": " + type + " is unsupported");
        }
        this.mAnnType = type;
    }

    public boolean checkAnnotationType(AnnType type) {
        return type == AnnType.ON_DENIED_CALLBACK
                || type == AnnType.ON_GRANTED_CALLBACK;
    }

    public AnnType getAnnotationType() {
        return mAnnType;
    }

    public String getMethodDesc() {
        return Utils.METHOD_DESC_CALLBACK;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        CallbackAnnotation that = (CallbackAnnotation) o;
        return mAnnType == that.mAnnType;
    }

    @Override
    public int hashCode() {
        return Objects.hash(mAnnType);
    }

    @Override
    public String toString() {
        return "CallbackAnnotation{" +
                "mAnnType=" + mAnnType +
                "} " + super.toString();
    }

    public void checkUsedRight(String desc) {
        if (getMethodDesc() == null || "".equals(getMethodDesc())) return;
        if (!getMethodDesc().equals(desc)) {
            throw new RuntimeException(mAnnType + " can only be used to annotate the method whose desc is like " + desc);
        }
    }
}
